﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using ValidationFramework.Facts.Research.Fakes;

namespace ValidationFramework.Facts.Research
{
	public class PropertyRuleDictionaryFacts
	{
		// --- Internal Classes
		public class Person
		{
			public string Name { get; set; }
			public string NickName { get; set; }
			public int Awesomeness { get; set; }
		}
		[Fact]
		public void On_Construction_Should_Add_Keys_For_All_Public_Properties_Of_Specified_Type()
		{
			// --- Act
			var propertyDictionary = new PropertyRuleDictionary<PropertyValueRule>(typeof(Person).TypeHandle);
			
			// --- Assert
			Assert.True(propertyDictionary.Keys.Count == 3, "After construction it has the wrong number of dictionary entries.");

		}
		[Fact]
		public void On_Construction_If_No_Rules_Are_Supplied_Values_For_Keys_Should_Be_Non_Null_Empty_Lists()
		{
			// --- Act
			var propertyDictionary = new PropertyRuleDictionary<PropertyValueRule>(typeof(Person).TypeHandle);

			// --- Assert
			foreach (var item in propertyDictionary)
			{
				Assert.True(item.Value != null, string.Format("The property rule list at key '{0}' was null", item.Key));
				Assert.True(item.Value.Count == 0, string.Format("The property rule list at key '{0}' was not empty", item.Key));
			}
		}
		[Fact]
		public void Add_Rules_Should_Sort_Rule_To_Correct_Key()
		{
			// --- Arrange
			var fakeValueRules = new List<PropertyValueRule>();
			fakeValueRules.Add(new PropertyValueRule(new AlwaysPassValueValidator()) { PropertyName = "Name" });
			fakeValueRules.Add(new PropertyValueRule(new AlwaysPassValueValidator()) { PropertyName = "NickName" });
			fakeValueRules.Add(new PropertyValueRule(new AlwaysPassValueValidator()) { PropertyName = "NickName" });
			fakeValueRules.Add(new PropertyValueRule(new AlwaysPassValueValidator()) { PropertyName = "Awesomeness" });

			// --- Act
			var propertyDictionary = new PropertyRuleDictionary<PropertyValueRule>(typeof(Person).TypeHandle);
			propertyDictionary.AddRules(fakeValueRules);

			// --- Assert
			Assert.True(propertyDictionary["Name"].Count == 1, "Rules for the 'Name' property were supplied but an incorrect number made it to the 'Name' key on the dictionary");
			Assert.True(propertyDictionary["NickName"].Count == 2, "Rules for the 'NickName' property were supplied but an incorrect number made it to the 'NickName' key on the dictionary");
			Assert.True(propertyDictionary["Awesomeness"].Count == 1, "Rules for the 'Awesomeness' property were supplied but an incorrect number made it to the 'Awesomeness' key on the dictionary");
		}
	}
}
